package com.fingard.dsp.bank.directbank.fjnx12;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.*;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.fingard.dsp.bank.helpers.YBTHelper.getBatSeqNo;

public class FJNX12BatPayRec extends FJNX12Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return null;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req9188.reqHeader);
        retAts.reqSeqID = p_req9188.reqBatchNO;

        try {
            // 批量代扣请求文件内容
            StringBuilder sbFileContent = new StringBuilder();
            // 批次号映射文件内容，以资金批次号命名映射文件，文件内容为发送银行的批次号（6位）
            StringBuilder seqNoMappingContent = new StringBuilder();

            Date dayCutTime = getDayCutTime(p_req9188.getPayDateTime());
            String tmpBatSeqNoPath = getDataFileDirectory(dayCutTime) + File.separator + "batrec";
            String tmpBatSeqNo = getBatSeqNo(tmpBatSeqNoPath, 4);
            String transDate = Format.Date8Format.format(dayCutTime);
            String totalNum = p_req9188.totalNum;
            String totalAmt = StringHelper.amountMultiply100(p_req9188.totalAmt);
            String insuid = bankFront.corpNo;

            String tmpReqHeader = MessageFormat.format("{0}@|@{1}@|@{2}", tmpBatSeqNo, totalNum, totalAmt);
            sbFileContent.append(tmpReqHeader);

            int seqNo = 0;
            while (p_req9188.readRecord()) {
                if (seqNoMappingContent.length() > 0) {
                    seqNoMappingContent.append("\r\n");
                }
                if (sbFileContent.length() > 0) {
                    sbFileContent.append("\r\n");
                }
                seqNo++;
                String seqNoId = String.valueOf(seqNo);
                String userID = transDate + p_req9188.readedDetail.askNumber;
                String certType = convertCertTypeToBank(p_req9188.readedDetail.certType);
                String certNum = p_req9188.readedDetail.certNum;
                String payName = p_req9188.readedDetail.payName;
                String payAct = p_req9188.readedDetail.payAct;
                String payAmount = StringHelper.amountMultiply100(p_req9188.readedDetail.payAmount);
                // 序号|用户编号（30位）|证件类型（3位）|证件号码（32位）|户名（100位）|签约账户（32位）|金额（17位）
                sbFileContent.append(MessageFormat.format("{0}@|@{1}@|@{2}@|@{3}@|@{4}@|@{5}@|@{6}", seqNoId, userID, certType, certNum, payName, payAct, payAmount));
                seqNoMappingContent.append(seqNoId).append(",").append(p_req9188.readedDetail.askNumber);
            }

            //批次流水映射文件
            String tmpLocalSeqFilePath = tmpBatSeqNoPath + File.separator + p_req9188.reqBatchNO + "_" + tmpBatSeqNo + ".txt";
            WriteBankLogLn2("批次流水映射文件路径: " + tmpLocalSeqFilePath);
            FileHelper.writeFile(tmpLocalSeqFilePath, seqNoMappingContent.toString(), getCharset());

            //批次请求文件
            String fileName = insuid + "DS" + transDate + tmpBatSeqNo + "01";
            String tmpLocalFilePath = getTempFileDirectory(dayCutTime) + File.separator + "batrec" + File.separator + fileName;
            WriteBankLogLn2("批次请求文件保存本机路径:" + tmpLocalFilePath);
            WriteBankLogLn2("批次请求文件内容:\r\n" + sbFileContent.toString());
            FileHelper.writeFile(tmpLocalFilePath, sbFileContent.toString(), getCharset());

            //上送FTP
            FtpSet ftpSet = bankFront.getFtpSet("bat");
            MixFtp mixFtp = new MixFtp(ftpSet);
            String insuranceType = getBankConfig().getValueAsString("insuranceType");
            String uploadFilePath = StringHelper.trimEnd(ftpSet.upDir, "/") + "/" + "3011/" + insuranceType;
            WriteBankLogLn2("上传FTP路径：" + uploadFilePath + "/" + fileName);
            FtpReceiver ftpReceiver = mixFtp.uploadFileToDir(tmpLocalFilePath, uploadFilePath, fileName);

            retAts.respCode = "0";
            if (!ftpReceiver.isCompleted) {
                retAts.respCode = "-1";
                retAts.respInfo = ftpReceiver.connMsg;
            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                retAts.respInfo = "批量代收请求文件上传失败！";
                retAts.transState = "BatchFailed";
                retAts.payInfoCode = "E9999";
            } else {
                WriteBankLogLn2("批量代收请求文件上传成功！");
                String okFileName = fileName + ".ok";// .ok文件 与批扣文件同名的空文件
                String tmpLocalOkFilePath = getTempFileDirectory(dayCutTime) + File.separator + "batrec" + File.separator + okFileName;
                WriteBankLogLn2("批量代收请求.ok文件保存本机路径:" + tmpLocalOkFilePath);
                FileHelper.writeFile(tmpLocalOkFilePath, "", getCharset());
                ftpReceiver = mixFtp.uploadFileToDir(tmpLocalOkFilePath, uploadFilePath, okFileName);

                boolean isCompleted = false;
                if (!ftpReceiver.isCompleted) {
                    retAts.respCode = "-1";
                    retAts.respInfo = ftpReceiver.connMsg;
                } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                    retAts.respInfo = "批量代收请求.ok文件上传失败！";
                    retAts.transState = "BatchFailed";
                    retAts.payInfoCode = "E9999";
                } else {
                    isCompleted = true;
                    WriteBankLogLn2("批量代收请求.ok文件上传成功！");
                }
                if (isCompleted) {
                    XmlTextWriter xmlWriter = new XmlTextWriter();
                    xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
                    xmlWriter.writeStartElement("INSURFILEINFOREQ");
                    xmlWriter.writeStartElement("MAIN");
                    xmlWriter.writeElementString("BANKCODE", "");
                    xmlWriter.writeElementString("INSUID", insuid);
                    xmlWriter.writeElementString("INSUSRNO", getQryTransID());
                    xmlWriter.writeElementString("TRANSRDATE", transDate);
                    xmlWriter.writeElementString("TRANSRTIME", Format.Time6Format.format(p_req9188.getPayDateTime()));
                    xmlWriter.writeElementString("TRANSCODE", "3011");
                    xmlWriter.writeElementString("ZONENO", "");
                    xmlWriter.writeElementString("FILETYPE", "01");
                    xmlWriter.writeElementString("BATNO", p_req9188.reqBatchNO);
                    xmlWriter.writeElementString("FILENAME", fileName);
                    xmlWriter.writeElementString("BUSIDATE", Format.Date8Format.format(p_req9188.getPayDateOnly()));
                    xmlWriter.writeEndDocument();

                    String[] tmpRetStr = sendToBank(xmlWriter.toXmlString(), "3011");

                    if (tmpRetStr[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String tmpResultCode = tmpBkReader.getFirstText("/INSURFILEINFORSP/RESULTCODE");
                            String tmpErrInfo = tmpBkReader.getFirstText("/INSURFILEINFORSP/ERRINFO");
                            if (tmpResultCode != null) {
                                retAts.respCode = "0";
                                retAts.respInfo = tmpErrInfo;
                                retAts.transState = tmpResultCode;
                                retAts.payInfoCode = tmpResultCode;
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = "银行返回报文缺失处理结果代码‘RESULTCODE’节点";
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpSbMsg.toString();
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetStr[1];
                    }
                }
            }
        } catch (Exception ex) {
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req9198.reqHeader);
        retAts.reqSeqID = p_req9198.reqBatchNO;

        try {
            Date dayCutTime = getDayCutTime(p_req9198.getBgnDateTime());
            String tmpBatSeqNoPath = getDataFileDirectory(dayCutTime) + File.separator + "batrec";
            File tmpSeqNoMappingDir = new File(tmpBatSeqNoPath);
            if (tmpSeqNoMappingDir.exists()) {
                File[] tmpSeqMappingFileList = tmpSeqNoMappingDir.listFiles();
                boolean isContinue = false;
                String tmpSeqMappingFileName = "";
                for (File tmpSeqMappingFile : tmpSeqMappingFileList) {
                    if (tmpSeqMappingFile.getName().contains(p_req9198.reqBatchNO)) {
                        isContinue = true;
                        tmpSeqMappingFileName = tmpSeqMappingFile.getName();
                        break;
                    }
                }

                boolean isCompleted = false;//FTP文件下载完成标志
                boolean fileExist = true;//本地路径是否存在回盘文件
                String localDownloadFilePath = "";// 本地回盘文件路径
                String[] seqNoArray = null;// 本地批次流水映射文件内容
                if (isContinue) {
                    String[] tmpBatSeqMappingArray = tmpSeqMappingFileName.substring(0, tmpSeqMappingFileName.lastIndexOf('.')).split("_");
                    String tmpBatchNoId = tmpBatSeqMappingArray[1];
                    String batSeqNoPath = tmpBatSeqNoPath + File.separator + tmpSeqMappingFileName;
                    WriteBankLogLn2("本地批量代扣流水映射文件路径:" + batSeqNoPath);
                    if (!new File(batSeqNoPath).exists()) {
                        retAts.respCode = "-1";
                        retAts.respInfo = "本地批次代扣流水映射文件不存在!";
                        return retAts;
                    }
                    String seqNoMappingContent = FileHelper.readFileText(batSeqNoPath, getCharset());
                    WriteBankLogLn2("本地批量代扣流水映射文件内容:\r\n" + seqNoMappingContent);
                    seqNoArray = seqNoMappingContent.split("\r\n");

                    String tmpDownloadFileName = bankFront.corpNo + "DS" + Format.Date8Format.format(dayCutTime) + tmpBatchNoId + "_ret";
                    localDownloadFilePath = createTempFileDirectory(dayCutTime) + File.separator + "batrec" + File.separator + tmpDownloadFileName;

                    // 本地无回盘文件，则到FTP目录下载
                    if (!FileHelper.existFile(localDownloadFilePath)) {
                        fileExist = false;
                        FtpSet ftpSet = bankFront.getFtpSet("bat");
                        String insuranceType = getBankConfig().getValueAsString("insuranceType");
                        String downFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + "1034/" + insuranceType;
                        WriteBankLogLn2("批量代扣回盘文件FTP下载路径:" + downFilePath + "/" + tmpDownloadFileName);

                        MixFtp mixFtp = new MixFtp(ftpSet);
                        FtpReceiver ftpReceiver = mixFtp.downloadFileFromDir(downFilePath, tmpDownloadFileName, localDownloadFilePath);
                        WriteBankLogLn2("批量代扣回盘文件保存本机路径:" + localDownloadFilePath);

                        if (!ftpReceiver.isCompleted) {
                            retAts.respCode = "-1";
                            retAts.respInfo = ftpReceiver.connMsg;
                        } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                            retAts.respInfo = "批量代扣回盘文件下载失败！";
                            retAts.transState = "BatchFailed";
                            retAts.payInfoCode = "E9999";
                        } else {
                            isCompleted = true;
                            WriteBankLogLn2("批量代扣回盘文件下载成功！");
                        }
                    }

                }
                if (fileExist || isCompleted) {
                    String tmpStrRet = FileHelper.readFileText(localDownloadFilePath, getCharset());
                    WriteBankLogLn2("本地批量代扣回盘文件内容:\r\n" + tmpStrRet);
                    if (StringHelper.hasAnyChar(tmpStrRet)) {
                        retAts.respCode = "0";
                        StringReader strReader = new StringReader(tmpStrRet);
                        BufferedReader tmpReader = new BufferedReader(strReader);
                        tmpReader.readLine();
                        while (true) {
                            String eachline = tmpReader.readLine();
                            if (eachline == null) {
                                break;
                            }
                            if (eachline.indexOf("@|@") > 0) {
                                String[] detailNodes = eachline.split("@|@");
                                for (String tmpSeqNo : seqNoArray) {
                                    if (StringHelper.isNullOrEmpty(tmpSeqNo)) {
                                        continue;
                                    }
                                    if ((tmpSeqNo.split(",")[0]).equals(detailNodes[0])) {
                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

                                        tmpRetDetail.bkSeq = detailNodes[0];
                                        tmpRetDetail.payAmount = StringHelper.amountDivide100(detailNodes[6]);
                                        tmpRetDetail.payName = detailNodes[4];
                                        tmpRetDetail.payAct = detailNodes[5];
                                        tmpRetDetail.postScript = tmpSeqNo.split(",")[1];
                                        tmpRetDetail.result = detailNodes[9];
                                        tmpRetDetail.payInfoCode = detailNodes[9];
                                        tmpRetDetail.memo = detailNodes[10];
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = "银行返回明细数据格式非法!";
                            }
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "批次结果文件内容为空!";
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "本地批次流水映射目录不存在，未发生过批次交易!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}